package cn.com.shopec.erp.system.common;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 
 * @ClassName ActionContext
 * @Description 从session获取属性
 * @author chengui
 * @date 2013-6-6 上午11:07:38
 */
public class ActionContext {
	
	private static final Log log = LogFactory.getLog(ActionContext.class);

	private static ThreadLocal<ActionContext> actionContext = new ActionContextThreadLocal();
	
	private Map<String,Object> context;
	
	private static final String HTTP_REQUEST = "HTTP_REQUEST";
	
	private static final String HTTP_RESPONSE = "HTTP_RESPONSE";
	
	private static ActionContext getActionContext(){
		ActionContext context = actionContext.get();
		if(context == null) {
			context = new ActionContext(new HashMap<String,Object>());
			actionContext.set(context);
		}
		return actionContext.get(); //从ThreadLocal中，获得当前线程的ActionContext实例
	}
	
	/**
	 * 将Request实例存入action context中，应该只在ActionFilter中调用一次
	 * @param request
	 */
	public static void setRequest(HttpServletRequest request) {
		ActionContext context = getActionContext();
		context.put(HTTP_REQUEST, request);
	}
	
	/**
	 * 将Response实例存入action context中，应该只在ActionFilter中调用一次
	 * @param response
	 */
	public static void setResponse(HttpServletResponse response) {
		ActionContext context = getActionContext();
		context.put(HTTP_RESPONSE, response);
	}
	/**
	 * 取所有cookie
	 * @return
	 */
	public static Cookie[] getCookies() {
		HttpServletRequest request = (HttpServletRequest)getActionContext().get(HTTP_REQUEST);
		Cookie[] cookies = request.getCookies();
		return cookies;
	}
	
	/**
	 * 根据key，取一个cookie
	 * @param key
	 * @return
	 */
	public static Cookie getCookie(String key) {
		if(key == null) {
			return null;
		}
		HttpServletRequest request = (HttpServletRequest)getActionContext().get(HTTP_REQUEST);
		Cookie[] cookies = request == null ? null : request.getCookies();
		if(cookies != null) {
			for(Cookie cookie:cookies){
				if(cookie.getName().equals(key)) {
					return cookie;
				}
			}
		}
		return null;
	}
	
	/**
	 * 根据key，取cookie值
	 * @param key
	 * @return
	 */
	public static String getCookieValue(String key) {
		if(key == null) {
			return null;
		}
		HttpServletRequest request = (HttpServletRequest)getActionContext().get(HTTP_REQUEST);
		Cookie[] cookies = request == null ? null : request.getCookies();
		if(cookies != null) {
			for(Cookie cookie:cookies){
				if(cookie.getName().equals(key)) {
					return cookie.getValue();
				}
			}
		}
		return null;
	}
	
	/**
	 * 添加cookie
	 * @param cookie
	 */
	public static void addCookie(Cookie cookie) {
		HttpServletResponse response = (HttpServletResponse)getActionContext().get(HTTP_RESPONSE);
		response.addCookie(cookie);
	}
	
	/**
	 * 获取session中某属性的值
	 * @param attributeName
	 * @return
	 */
	public static Object getSessionAttribute(String attributeName) {
		HttpServletRequest request = (HttpServletRequest)getActionContext().get(HTTP_REQUEST);
		if(request == null){
			return null;
		}
		HttpSession session = request.getSession();
		if(session == null){
			log.error("Session is null!!!!");
			return null;
		}else{
			return session.getAttribute(attributeName);
		}
	}
	
	/**
	 * 设置session中某属性的值
	 * @param attributeName
	 * @param value
	 */
	public static void setSessionAttribute(String attributeName,Object value) {
		HttpServletRequest request = (HttpServletRequest)getActionContext().get(HTTP_REQUEST);
		if(request != null){
			HttpSession session = request.getSession();
			session.setAttribute(attributeName, value);
		}else{
			//暂时不处理request实例是null的情况
		}
	}
	
	/**
	 * 使session无效（在用户退出时使用）
	 */
	public static void sessionInvalide() {
		HttpServletRequest request = (HttpServletRequest)getActionContext().get(HTTP_REQUEST);
		if(request != null) {
			request.getSession().invalidate();
		}
	}
	
	/**
	 * 获取已登录的管理员的id，如果返回值为0，则说明未登录
	 * @return
	 */
	public static int getAdminId() {
		int id = 0;
		Integer idInSess = (Integer)getSessionAttribute(Constants.ADMIN_USER_SESSION_KEY);
//		if(StringUtils.hasText(idStr)) {
//			try {
//				id = Integer.parseInt(idStr);
//			}catch(Exception e) {
//				log.error(e.getMessage(), e);
//			}
//		}
		id = idInSess == null || idInSess < 0 ? 0 : idInSess; //id不能小于0
//		id = id < 0 ? 0 : id; //id不能小于0
		return id;
	}
	
	/**
	 * 获取登录用户的id
	 * @return
	 */
	public static int getLoginUserId() {
		int id = 0;
		boolean inSession = true;
		String idStr = (String)getSessionAttribute(Constants.WEBSITE_USER_SESSION_KEY); //先尝试从session取
		if(idStr == null) { //session中没有登录用户id，可能是用户没有登录，也可能是集群下，session未复制过来
			inSession = false; //说明没在session中有id
			Cookie cookie = getCookie(Constants.WEBSITE_USER_LOGIN_STATUS_KEY); //从cookie判断是否已经登录
			if("1".equals(cookie == null ? null : cookie.getValue())){ //已经登录了
				cookie = getCookie(Constants.WEBSITE_USER_COOKIE_KEY); //得到cookie中的用户信息
				String userKeyInCookie = StringUtils.getNotNullString(cookie == null ? null : cookie.getValue()).trim(); 
				
				try{
					userKeyInCookie = CipherUtils.decrypt(userKeyInCookie);
				}catch(Exception e) {
					log.error(e.getMessage(),e);
					userKeyInCookie = null;
				}
				
				if(StringUtils.hasText(userKeyInCookie)) { //不为空串才处理
					int n = userKeyInCookie.indexOf(',');
					idStr = n > 0 ? userKeyInCookie.substring(0, n) : "";
				}
			}
		}
		if(!StringUtils.hasText(idStr)) { //如果此时还是没有id值，则说明用户没登录
			//Do nothing
		}else{
			try{
				id = Integer.parseInt(idStr); //尝试将字符串的id值，转为数字
			}catch(NumberFormatException nfe) {
				log.error(nfe.getMessage(),nfe);
			}
		}
		if(id > 0 && !inSession) { //如果session中没有用户id信息，则把得到的id值存入session（主要针对集群中session不能复制的问题）
			setSessionAttribute(Constants.WEBSITE_USER_SESSION_KEY,String.valueOf(id)); 
		}
		
		return id;
	}
	
	/**
	 * 判断用户是否已经登录
	 * @return
	 */
	public static boolean isLoginUser() {
		int loginUserId = getLoginUserId();
		if(loginUserId > 0) {
			return true;
		}else{
			return false;
		}
	}

	private ActionContext(Map<String,Object> context){
		this.context = context;
	}
	
	private Object get(String key) {
		return this.context.get(key);
	}
	
	private void put(String key,Object value) {
		this.context.put(key, value);
	}
	
	
	private static class ActionContextThreadLocal extends ThreadLocal<ActionContext> {

		protected ActionContext initialValue() {
			//初始化一个ActionContext，确保当前线程调用ThreadLoacl的get方法时，能得到一个构造好的ActionContext实例
			return new ActionContext(new HashMap<String,Object>());
		}
	}
}
